Next: Debugging actions, Previous: Report errors, Up: Wisent Parsing [Contents][Index]
The error recovery mechanism of the Wisent’s parser conforms to the one Bison uses. See (bison)Error Recovery, in the Bison manual for details.
To recover from a syntax error you must write rules to
recognize the special token error. This is a
terminal symbol that is automatically defined and reserved for
error handling.
When the parser encounters a syntax error, it pops the state
stack until it finds a state that allows shifting the
error token. After it has been shifted, if the old
look-ahead token is not acceptable to be shifted next, the parser
reads tokens and discards them until it finds a token which is
acceptable.
Strategies for error recovery depend on the choice of error rules in the grammar. A simple and useful strategy is simply to skip the rest of the current statement if an error is detected:
(statement (( error ?; )) ;; on error, skip until ';' is read
)
It is also useful to recover to the matching close-delimiter of an opening-delimiter that has already been parsed:
(primary (( ?{ expr ?} ))
(( ?{ error ?} ))
…
)
Note that error recovery rules may have actions, just as any other rules can. Here are some predefined hooks, variables, functions or macros, useful in such actions:
The number of parse errors encountered so far.
non-nil means that the parser is recovering.
This variable only has meaning in the scope of
wisent-parse.
Call the user supplied error reporting function with message msg (see Report errors).
For an example of use, See wisent-skip-token.
Resume generating error messages immediately for subsequent syntax errors.
The parser suppress error message for syntax errors that happens shortly after the first, until three consecutive input tokens have been successfully shifted.
Calling wisent-errok in an action, make error
messages resume immediately. No error messages will be
suppressed if you call it in an error rule’s
action.
For an example of use, See wisent-skip-token.
Discard the current lookahead token. This will cause a new lexical token to be read.
In an error rule’s action the previous lookahead
token is reanalyzed immediately. wisent-clearin
may be called to clear this token.
For example, suppose that on a parse error, an error
handling routine is called that advances the input stream to
some point where parsing should once again commence. The next
symbol returned by the lexical scanner is probably correct.
The previous lookahead token ought to be discarded with
wisent-clearin.
For an example of use, See wisent-skip-token.
Abort parsing and save the lookahead token.
Change the region of text matched by the current
nonterminal. start and end are
respectively the beginning and end positions of the region
occupied by the group of components associated to this
nonterminal. If start or end values are
not a valid positions the region is set to
nil.
For an example of use, See wisent-skip-token.
List of functions to be called when discarding a lexical
token. These functions receive the lexical token discarded.
When the parser encounters unexpected tokens, it can discards
them, based on what directed by error recovery rules. Either
when the parser reads tokens until one is found that can be
shifted, or when an semantic action calls the function
wisent-skip-token or
wisent-skip-block. For language specific hooks,
make sure you define this as a local hook.
For example, in Semantic, this hook is set to the
function wisent-collect-unmatched-syntax to
collect unmatched lexical tokens (see Useful
functions).
Skip the lookahead token in order to resume parsing.
Return nil. Must be used in error recovery
semantic actions.
It typically looks like this:
(wisent-message "%s: skip %s" $action
(wisent-token-to-string wisent-input))
(run-hook-with-args
'wisent-discarding-token-functions wisent-input)
(wisent-clearin)
(wisent-errok)))
Safely skip a block in order to resume parsing. Return
nil. Must be used in error recovery semantic
actions.
A block is data between an open-delimiter (syntax class
() and a matching close-delimiter (syntax class
)):
(a parenthesized block)
[a block between brackets]
{a block between braces}
The following example uses wisent-skip-block
to safely skip a block delimited by
‘LBRACE’ ({) and
‘RBRACE’ (}) tokens,
when a syntax error occurs in
‘other-components’:
(block ((LBRACE other-components RBRACE))
((LBRACE RBRACE))
((LBRACE error)
(wisent-skip-block))
)
Next: Debugging actions, Previous: Report errors, Up: Wisent Parsing [Contents][Index]